#include "stm32f10x.h" // STM32标准库
#include "Myusart.h"   // 当前头文件

// ===== 全局变量定义 =====
u8 USART1_RX_BUF[USART1_REC_LEN]; // USART1接收缓冲区（200字节）

/*
USART1接收状态寄存器（16位）：
位15: 接收完成标志（1=完成，0=未完成）
位14: 接收到0x0D（回车符）标志
位0-13: 接收到的有效字节数
*/
u16 USART1_RX_STA = 0; // 初始状态：所有标志位清零

// USART1初始化函数
void USART1_Init(u32 BaudRate)
{
    // ===== 1. 使能外设时钟 =====
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);   // 使能GPIOA时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);  // 使能USART1时钟

    // ===== 2. 配置GPIO引脚 =====
    GPIO_InitTypeDef GPIO_InitStructureTX; // TX引脚配置结构体
    
    // 配置PA9为USART1_TX（复用推挽输出）
    GPIO_InitStructureTX.GPIO_Pin = GPIO_Pin_9;         // 选择引脚9
    GPIO_InitStructureTX.GPIO_Speed = GPIO_Speed_50MHz; // 最大输出速度50MHz
    GPIO_InitStructureTX.GPIO_Mode = GPIO_Mode_AF_PP;   // 复用推挽输出模式
    GPIO_Init(GPIOA, &GPIO_InitStructureTX);            // 应用配置到GPIOA

    GPIO_InitTypeDef GPIO_InitStructureRX; // RX引脚配置结构体
    
    // 配置PA10为USART1_RX（浮空输入）
    GPIO_InitStructureRX.GPIO_Pin = GPIO_Pin_10;            // 选择引脚10
    GPIO_InitStructureRX.GPIO_Mode = GPIO_Mode_IN_FLOATING; // 浮空输入模式
    GPIO_Init(GPIOA, &GPIO_InitStructureRX);                // 应用配置到GPIOA

    // ===== 3. 配置USART参数 =====
    USART_InitTypeDef USART_InitStructure; // USART配置结构体
    
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; // 收发模式
    USART_InitStructure.USART_BaudRate = BaudRate;                  // 设置波特率
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;     // 8位数据长度
    USART_InitStructure.USART_StopBits = USART_StopBits_1;          // 1位停止位
    USART_InitStructure.USART_Parity = USART_Parity_No;             // 无校验位
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // 无硬件流控
    
    // 应用USART配置
    USART_Init(USART1, &USART_InitStructure);
    
    // 使能USART1
    USART_Cmd(USART1, ENABLE);
    
    // 清除传输完成标志（避免首次发送错误）
    USART_ClearFlag(USART1, USART_FLAG_TC);
    
    // 使能USART1接收中断（RXNE=接收寄存器非空中断）
    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);

    // ===== 4. 配置中断优先级 =====
    NVIC_InitTypeDef NVIC_InitStructure; // NVIC配置结构体
    
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;         // 选择USART1中断通道
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;           // 使能中断
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; // 抢占优先级2
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;        // 子优先级3
    NVIC_Init(&NVIC_InitStructure); // 应用中断配置
}

// ===== USART1中断服务函数 =====
// 当USART1接收到数据时自动调用此函数
void USART1_IRQHandler()
{
    u8 r; // 存储接收到的字节
    
    // 检查是否发生接收中断（RXNE=接收数据寄存器非空）
    if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
    {
        // 读取接收到的字节（读取后RXNE位自动清零）
        r = USART_ReceiveData(USART1);
        
        // 检查接收是否完成（bit15是否为0）
        if ((USART1_RX_STA & 0x8000) == 0)
        {
            // 检查是否已收到回车符（bit14是否为1）
            if (USART1_RX_STA & 0x4000)
            {
                /* 情况1：已收到回车符(0x0D)，等待换行符(0x0A) */
                
                if (r != 0x0a)
                {
                    // 错误：收到回车后未收到换行符
                    USART1_RX_STA = 0; // 重置接收状态
                }
                else
                {
                    // 正确：收到换行符，标记接收完成
                    USART1_RX_STA |= 0x8000; // 设置bit15=1
                }
            }
            else
            {
                /* 情况2：正常接收数据 */
                
                if (r == 0x0d)
                {
                    // 收到回车符(0x0D)，设置回车标志
                    USART1_RX_STA |= 0x4000; // 设置bit14=1
                }
                else
                {
                    // 存储接收到的普通数据字节
                    USART1_RX_BUF[USART1_RX_STA & 0x3fff] = r;
                    
                    // 增加接收计数器（低14位）
                    USART1_RX_STA++;
                    
                    // 检查缓冲区是否溢出
                    if (USART1_RX_STA > (USART1_REC_LEN - 1))
                    {
                        // 缓冲区溢出，重置接收状态
                        USART1_RX_STA = 0;
                    }
                }
            }
        }
    }
}